package com.cy.aliyun_vod_upload;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.vod.upload.VODUploadCallback;
import com.alibaba.sdk.android.vod.upload.VODUploadClient;
import com.alibaba.sdk.android.vod.upload.VODUploadClientImpl;
import com.alibaba.sdk.android.vod.upload.model.UploadFileInfo;
import com.alibaba.sdk.android.vod.upload.model.VodUploadResult;
import com.alibaba.sdk.android.vod.upload.model.VodInfo;
import com.google.gson.Gson;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** AliyunVodUploadPlugin */
public class AliyunVodUploadPlugin implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler {
  private Handler platformThreadHandler = new Handler(Looper.getMainLooper());
  private MethodChannel channel;
  private EventChannel event;
  private EventChannel.EventSink eventSink;
  private Context activeContext;
  // 阿里云上传实例
  private VODUploadClient uploader;
  // 上传的校验信息
  private AuthInitModel authInitModel;
  // 初始化实例（使用auth）
  private void authInit(@NonNull MethodCall call, @NonNull Result result) {
    authInitModel = new AuthInitModel();
    authInitModel.setUploadAuth(call.argument("uploadAuth"));
    authInitModel.setUploadAddress(call.argument("uploadAddress"));

    uploader = new VODUploadClientImpl(activeContext);
    // 设置回调
    VODUploadCallback callback = new VODUploadCallback(){
      @Override
      public void onUploadSucceed(UploadFileInfo info, VodUploadResult result) {
        Log.i("vod","成功回调 ------------------" + info.getFilePath());
        final Map<String, Object> eventData = new HashMap<>();
        eventData.put("event", "OnUploadFinishedListener");
        eventData.put("uploadFileInfo", info);
        eventData.put("vodUploadResult", result);
        sendEvent(ParamUtils.toJson(eventData));
      }

      @Override
      public void onUploadFailed(UploadFileInfo info, String code, String message) {
        Log.i("vod","失败回调 ------------------ " + info.getFilePath() + " " + code + " " + message);
        final Map<String, Object> eventData = new HashMap<>();
        eventData.put("event", "OnUploadFailedListener");
        eventData.put("uploadFileInfo", info);
        eventData.put("code", code);
        eventData.put("message", message);
        sendEvent(ParamUtils.toJson(eventData));
      }

      @Override
      public void onUploadProgress(UploadFileInfo info, long uploadedSize, long totalSize) {
        Log.i("vod","进度回调 ------------------ " + info.getFilePath() + " " + uploadedSize + " " + totalSize);
        final Map<String, Object> eventData = new HashMap<>();
        eventData.put("event", "OnUploadProgressListener");
        eventData.put("uploadFileInfo", info);
        eventData.put("uploadedSize", uploadedSize);
        eventData.put("totalSize", totalSize);
        sendEvent(ParamUtils.toJson(eventData));
      }

      @Override
      public void onUploadTokenExpired() {
        Log.i("vod","令牌失效 ------------- ");
        //重新刷新上传凭证：RefreshUploadVideo。
        final Map<String, Object> eventData = new HashMap<>();
        eventData.put("event", "OnUploadTokenExpiredListener");
        sendEvent(ParamUtils.toJson(eventData));
      }

      @Override
      public void onUploadRetry(String code, String message) {
        Log.i("vod","onUploadRetry ------------- ");
      }

      @Override
      public void onUploadRetryResume() {
        Log.i("vod","onUploadRetryResume ------------- ");
      }

      @Override
      public void onUploadStarted(UploadFileInfo uploadFileInfo) {
        Log.i("vod","开始上传 ------------- ");
        //uploadAuth及uploadAddress即为上传凭证和地址。
        uploader.setUploadAuthAndAddress(uploadFileInfo, authInitModel.getUploadAuth(), authInitModel.getUploadAddress());
        final Map<String, Object> eventData = new HashMap<>();
        eventData.put("event", "OnUploadStartedListener");
        eventData.put("uploadFileInfo", uploadFileInfo);
        sendEvent(ParamUtils.toJson(eventData));
      }
    };
    //上传初始化
    uploader.init(callback);
    result.success(true);
  }

  private void sendEvent(@NonNull String json) {
    platformThreadHandler.post(new Runnable() {
      @Override
      public void run() {
        eventSink.success(json);
      }
    });
  }

  // 添加文件
  private void addFile(@NonNull MethodCall call, @NonNull Result result) {
    String filePath = call.argument("filePath");
    HashMap<String, Object> vodInfoJson = call.argument("vodInfoModel");
    VodInfo vodInfo = ParamUtils.map2VodInfo(vodInfoJson);
    uploader.addFile(filePath, vodInfo);
    result.success(true);
  }

  // 开始上传
  private void startUpload(@NonNull MethodCall call, @NonNull Result result) {
    uploader.start();
    result.success(true);
  }

  // 刷新token
  private void resumeWithToken(@NonNull MethodCall call, @NonNull Result result) {
    // client.resumeWithAuth(call.argument("uploadAuth"));
    uploader.resumeWithToken(call.argument("keyId"), call.argument("keySecret"), call.argument("token"), call.argument("expireTime"));
    result.success(true);
  }

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "aliyun_vod_upload");
    channel.setMethodCallHandler(this);
    event = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "aliyun_vod_upload/event");
    event.setStreamHandler(this);
    activeContext = flutterPluginBinding.getApplicationContext();
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("getPlatformVersion")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    } else if (call.method.equals("authInit")) {
      authInit(call, result);
    } else if (call.method.equals("addFile")) {
      addFile(call, result);
    } else if (call.method.equals("startUpload")) {
      startUpload(call, result);
    } else if (call.method.equals("resumeUpload")) {
      resumeWithToken(call, result);
    } else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  @Override
  public void onListen(Object arguments, EventChannel.EventSink events) {
    this.eventSink = events;
  }

  @Override
  public void onCancel(Object arguments) {
    this.eventSink = null;
  }
}
